/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * Description:
 * Author: huawei
 * Create: 2022-06-22
 */
#include <linux/types.h>

#include "devmm_channel.h"
#include "svm_msg_client.h"
#include "svm_proc_mng.h"

int devmm_chan_report_process_status_d2h(
    struct devmm_svm_process *svm_process, struct devmm_svm_heap *heap, void *msg, u32 *ack_len)
{
    struct devmm_chan_process_status *process_status = (struct devmm_chan_process_status *)msg;

    devmm_modify_process_status(
        svm_process, process_status->head.dev_id, process_status->head.vfid, process_status->pid_status);

    return 0;
}

STATIC int devmm_query_process_status(struct devmm_svm_process *svm_proc,
    struct devmm_chan_process_status *process_status, struct devmm_ioctl_arg *arg)
{
    int ret;

    process_status->head.msg_id = DEVMM_CHAN_QUERY_PROCESS_STATUS_H2D_ID;
    process_status->head.process_id.hostpid = svm_proc->process_id.hostpid;
    process_status->head.process_id.vfid = (u16)arg->head.vfid;
    process_status->head.dev_id = (u16)arg->head.devid;

    ret = devmm_chan_msg_send(
        process_status, sizeof(struct devmm_chan_process_status), sizeof(struct devmm_chan_process_status));

    return ret;
}

int devmm_ioctl_query_process_status(struct devmm_svm_process *svm_proc, struct devmm_ioctl_arg *arg)
{
    processType_t process_type = arg->data.query_process_status_para.process_type;
    struct devmm_chan_process_status process_status = {{{0}}};
    processStatus_t proc_pid_status;
    processStatus_t *pid_status = NULL;
    int ret;

    if (process_type != PROCESS_CP1) {
        return DRV_ERROR_INVALID_VALUE;
    }

    pid_status = &arg->data.query_process_status_para.pid_status;

    proc_pid_status = devmm_get_process_status(svm_proc, arg->head.devid, arg->head.vfid);
    if (proc_pid_status != STATUS_NOMEM) {
        *pid_status = proc_pid_status;
        return 0;
    }

    ret = devmm_query_process_status(svm_proc, &process_status, arg);
    if (ret != 0) {
        devmm_drv_err("Msg send error! (ret=%d)\n", ret);
        return ret;
    }

    devmm_modify_process_status(
        svm_proc, process_status.head.dev_id, process_status.head.process_id.vfid, process_status.pid_status);
    *pid_status = process_status.pid_status;

    return 0;
}

